package org.qiyu.live.im.core.server.service.impl;

import com.alibaba.fastjson.JSON;
import io.netty.channel.ChannelHandlerContext;
import jakarta.annotation.Resource;
import org.qiyu.live.im.core.server.common.ChannelHandlerContextCache;
import org.qiyu.live.im.core.server.common.ImMsg;
import org.qiyu.live.im.core.server.common.ImMsgCodeEnum;
import org.qiyu.live.im.core.server.service.MsgAckServiceHandler;
import org.qiyu.live.im.core.server.service.IMRouterHandlerService;
import org.qiyu.live.im.dto.ImMsgBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.function.Function;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sfx
 * Date: 2023-10-12
 * Time: 20:16
 */
@Service
public class IMRouterHandlerServiceImpl implements IMRouterHandlerService {
    private static final Logger LOGGER = LoggerFactory.getLogger(IMRouterHandlerServiceImpl.class);

    @Resource
    private MsgAckServiceHandler msgAckServiceHandler;

    /**
     * router层把消息推送给im-core-server,就到达了im-core-server的rpc层---IMRouterHandlerService
     * 这里就要把消息推送给客户端(接收方)
     *
     * @param msgBody msgBody
     */
    @Override
    public void onReceive(ImMsgBody msgBody) {
        routeMessageToClient(msgBody);
        if (routeMessageToClient(msgBody)) {
            // 3. 这边发送完消息,要记录一下ack,等客户端接收到,重发次数为1
            msgAckServiceHandler.recordMsgAck(msgBody, 1);
            // 4. 发送MQ延迟消息,如果客户端没有返回ack,我们这边进行重试
            msgAckServiceHandler.sendDelayMessage(msgBody);
        }
    }

    @Override
    public boolean routeMessageToClient(ImMsgBody msgBody) {
        HashMap<String, List<Long>> map = new HashMap<>();
        // 1. 根据userId找到连接
        ChannelHandlerContext ctx = ChannelHandlerContextCache.get(msgBody.getUserId());
        if (ctx != null) {
            String msgId = UUID.randomUUID().toString();
            msgBody.setMessageId(msgId);
            // 该用户的连接还在
            // 2. 根据连接通道进行推送数据给接收方
            ImMsg respMsg = ImMsg.build(ImMsgCodeEnum.IM_BIZ_MSG.getCode(), JSON.toJSONString(msgBody));
            ctx.writeAndFlush(respMsg);
            return true;
        }
        return false;
    }
}